package key.w8.service;

import com.k8.common.config.K8ConfigProperties;
import com.k8.common.constants.CommonKeyConstants;
import com.k8.common.event.EventDeployer;
import com.k8.common.executor.ExecutorRepository;
import com.k8.common.factroy.BeanFactory;
import com.k8.common.factroy.loader.ExtensionDirector;
import com.k8.registry.RegistryManager;
import com.k8.registry.config.ReferenceBase;
import com.k8.registry.config.ServiceBase;
import com.k8.registry.util.RegistryUtil;
import com.k8.rpc.config.ProtocolConfig;
import com.k8.rpc.config.RegistryConfig;
import com.k8.rpc.expoter.ExporterListener;
import com.k8.rpc.invoke.InvokerManager;
import com.k8.rpc.metadata.AppMetaData;
import com.k8.rpc.metadata.ProtocolMetadata;
import com.k8.rpc.url.URL;
import com.k8.rpc.util.ConfigUtil;
import com.k8.rpc.util.URLUtils;
import key.w8.service.impl.TestServiceImpl1;
import key.w8.service.ref.TestService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import static com.k8.common.constants.SpiConstants.PROXY_TYPE_JAVASSIST;

/**
 * @Author: k8
 * @CreateTime: 2025-03-31
 * @Version: 1.0
 */
public class ServiceTest {
    /**
     * todo protocolUrl转化为remoting层配置的EnvironmentUtil还没做
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        CountDownLatch countDownLatch = new CountDownLatch(1);
        provider();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        consumer();
        countDownLatch.countDown();
    }
    public static void provider(){
        K8ConfigProperties k8ConfigProperties = new K8ConfigProperties();
        k8ConfigProperties.setHost("localhost");
        k8ConfigProperties.setPort(9981);
        k8ConfigProperties.setExporter("k8protocol");
        k8ConfigProperties.setAppName("testApp");
        URL systemConfigUrl = ConfigUtil.mapConfigToConstants(k8ConfigProperties);
        systemConfigUrl.setSide(CommonKeyConstants.PROVIDER);
        BeanFactory beanFactory = new BeanFactory(PROXY_TYPE_JAVASSIST);
        //***
        beanFactory.getOrRegistryBean(RegistryManager.class);
        //***
        ExtensionDirector extensionDirector = beanFactory.getExtensionDirector();
        systemConfigUrl.setExtensionAccessor(beanFactory.getExtensionDirector());
        ExecutorRepository defaultExecutorRepository = extensionDirector.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
        ExecutorService executorService = defaultExecutorRepository.getExecutorService(systemConfigUrl);
        EventDeployer eventDeployer = new EventDeployer(executorService);
        beanFactory.registryBean(eventDeployer);
        //这里应该交给定制化配置
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName("k8protocol");
        protocolConfig.setPort(9981);
        List<ProtocolConfig> protocolConfigList = List.of(protocolConfig);
        //定制化配置
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setHost("localhost");
        registryConfig.setPort(8848);
        registryConfig.setRegistryName("nacos");
        List<RegistryConfig> registryConfigList = List.of(registryConfig);
        List<URL> registryConfigUrls = registryConfigList.stream().map(registryConfig1 -> {
            return RegistryUtil.buildUrlByRegistryConfig(registryConfig1, systemConfigUrl, CommonKeyConstants.PROVIDER);
        }).collect(Collectors.toList());

        eventDeployer.addListener(new ExporterListener());

        List<URL> protocolUrls = protocolConfigList.stream().map(protocolConfig1 -> {
            return URLUtils.buildUrlByProtocolConfig(protocolConfig1, systemConfigUrl);
        }).collect(Collectors.toList());
        ServiceBase<TestService> serviceBase = new ServiceBase<>(beanFactory,systemConfigUrl,registryConfigUrls,protocolUrls);
        serviceBase.setInstance(new TestServiceImpl1());
        serviceBase.setVersion("1.0");
        serviceBase.setGroup("default");
        serviceBase.setInstance(new TestServiceImpl1());
        serviceBase.setType(TestService.class);
        serviceBase.export();
        Map<String, ProtocolMetadata> protocolMetadataMap = new HashMap<>();
        protocolConfigList.stream()
                .map(protocolConfig1 -> {
                    ProtocolMetadata protocolMetadata = new ProtocolMetadata();
                    protocolMetadata.setProtocol(protocolConfig.getName())
                            .setPort(protocolConfig.getPort());
                    return protocolMetadata;
                }).forEach(protocolMetadata -> {
                    protocolMetadataMap.put(protocolMetadata.getProtocol(),protocolMetadata);
                });
        AppMetaData appMetaData = new AppMetaData();
        appMetaData.setHost(k8ConfigProperties.getHost())
                .setPort(k8ConfigProperties.getPort())
                .setProtocols(protocolMetadataMap)
                //todo 修改id的方式
                .setServiceInstanceId(UUID.randomUUID().getLeastSignificantBits());
        serviceBase.exportApp(appMetaData);
    }
    public static void consumer() throws ExecutionException, InterruptedException, TimeoutException {
        K8ConfigProperties k8ConfigProperties = new K8ConfigProperties();
        k8ConfigProperties.setAppName("testApp");
        URL systemConfigUrl = ConfigUtil.mapConfigToConstants(k8ConfigProperties);
        systemConfigUrl.setSide(CommonKeyConstants.CONSUMER);
        BeanFactory beanFactory = new BeanFactory(PROXY_TYPE_JAVASSIST);
        //***
        beanFactory.getOrRegistryBean(RegistryManager.class);
        beanFactory.getOrRegistryBean(InvokerManager.class);
        //***
        ExtensionDirector extensionDirector = beanFactory.getExtensionDirector();
        systemConfigUrl.setExtensionAccessor(beanFactory.getExtensionDirector());
        ExecutorRepository defaultExecutorRepository = extensionDirector.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
        ExecutorService executorService = defaultExecutorRepository.getExecutorService(systemConfigUrl);
        EventDeployer eventDeployer = new EventDeployer(executorService);
        beanFactory.registryBean(eventDeployer);

        //定制化配置
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setHost("localhost");
        registryConfig.setPort(8848);
        registryConfig.setRegistryName("nacos");
        List<RegistryConfig> registryConfigList = List.of(registryConfig);
        List<URL> registryConfigUrls = registryConfigList.stream().map(registryConfig1 -> {
            return RegistryUtil.buildUrlByRegistryConfig(registryConfig1, systemConfigUrl, CommonKeyConstants.CONSUMER);
        }).collect(Collectors.toList());
        ReferenceBase<TestService> referenceBase = new ReferenceBase<>(beanFactory,registryConfigUrls,systemConfigUrl);
        referenceBase.setType(TestService.class)
                .setGroup("default")
                .setVersion("1.0")
                .setProtocol("k8protocol");
        TestService proxy = referenceBase.createProxy();
        Future<String> test = proxy.serviceString("test");
        String result = test.get(100000, TimeUnit.MILLISECONDS);
        System.out.println(result);
    }

}
